Laravel 加载之 bootstrap
简介
此章,主要讲的内容是 $this->bootstrap();
,Laravel
中的配置错误处理、配置日志记录、 检测应用环境 以及执行其他需要完成的任务 。
bootstrap
引导其实质是将下面的类中的 bootstrap
方法都执行一遍
protected $bootstrappers = [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
];
看一下 handle
方法
public function handle($request)
{
try {
$request->enableHttpMethodParameterOverride();
$response = $this->sendRequestThroughRouter($request); // 重点这一行
} catch (Exception $e) {
$this->reportException($e);
$response = $this->renderException($request, $e);
} catch (Throwable $e) {
$this->reportException($e = new FatalThrowableError($e));
$response = $this->renderException($request, $e);
}
$this->app['events']->dispatch(
new Events\RequestHandled($request, $response)
);
return $response;
}
代码中标注的重点的一行 $response = $this->sendRequestThroughRouter($request);
就是这个 handle
方法核心内容了。
我们继续看 sendRequestThroughRouter
方法
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
$this->bootstrap(); // 这就是这一章要讲的东西了
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
代码中标注的 $this->bootstrap();
就是 Laravel
引导配置加载的开始了,具体干了哪些工作呢:
- 加载
.env
文件,将配置加载到内存中 - 加载
config
目录下的所有配置文件 - 修改系统默认异常处理函数(如语法错误等),将其替代为
Laravel
的异常处理。这就是为什么在开发Laravel
应用时,语法出现错误,而报错信息已一种非常好看的界面显示的缘故 - 注册
Facades
,将Laravel
内的Facades
类中的静态属性$app
赋值为 服务容器 - 注册服务提供者,区分即时实例化和延时实例化,即时的不需要标识别名,而延时的需要标识别名,主要对
config/app.php
中providers
键对应值(服务器提供者类全名)进行分类 - 执行服务提供者的
boot
方法,其中路由文件加载和读取,就是在此步骤进行的
下面我们看一下 $this->bootstrap();
public function bootstrap()
{
if (! $this->app->hasBeenBootstrapped()) {
$this->app->bootstrapWith($this->bootstrappers());
}
}
这段代码是指,有没有进行过引导呀,有的话,不进入引导程序,没有则进入
下面我们看一下进入引导的,先看 $this->bootstrappers()
protected function bootstrappers()
{
return $this->bootstrappers;
}
这段就是返回了 bootstrappers
属性,它就是前言中展示的数组
下面我们看一下容器方法 bootstrapWith
public function bootstrapWith(array $bootstrappers)
{
$this->hasBeenBootstrapped = true;
foreach ($bootstrappers as $bootstrapper) {
$this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);
$this->make($bootstrapper)->bootstrap($this); // 核心在这
$this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
}
}
上面核心代码,就是遍历 $bootstrapper
数组,将里面的类实例化后,执行实例化后的 bootstrap
方法,将容器作为参数传入。
这一章,讲到这里,下一章我们看一下 $bootstrappers
数组的第一个值(类全名)的引导(即加载 .env
)
protected $bootstrappers = [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class, // 下一章看这个哦
\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
];